package edu.njust.httpmanager.controller;

import edu.njust.httpmanager.common.Result;
import edu.njust.httpmanager.common.UserContext;
import edu.njust.httpmanager.constance.ResponseCode;
import edu.njust.httpmanager.entity.User;
import edu.njust.httpmanager.entity.dto.UserDto;
import edu.njust.httpmanager.exception.CustomException;
import edu.njust.httpmanager.service.IEmailService;
import edu.njust.httpmanager.service.IUserService;
import edu.njust.httpmanager.utils.JwtUtil;
import edu.njust.httpmanager.utils.ValidateCodeUtil;
import edu.njust.httpmanager.utils.ValidatorUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
public class UserController {

    @Resource
    private IUserService userService;

    @Resource
    private IEmailService emailService;

    @PostMapping("/login")
    public Result<?> login(@RequestBody User user) {

        // 根据账号密码查询用户
        User realUser = userService.queryUser(user);

        if (realUser != null) {

            // 生成Token （存储了用户ID）
            Map<String, Object> claims = new HashMap<>();
            claims.put("id", realUser.getId());
            String token = JwtUtil.create(claims);

            // 返回token
            Map<String, Object> map = new HashMap<>();
            map.put("token", token);
            return Result.success(map);
        } else {
            // 查找用户不存在，返回错误信息
            return Result.error("账号和密码不一致");
        }
    }

    @GetMapping("/user")
    public Result<UserDto> getUserInfo() {

        UserDto userDto = new UserDto();

        User user = UserContext.getUser();

        userDto.setName(user.getName());
        userDto.setAccount(user.getAccount());
        userDto.setEmail(user.getEmail());

        return Result.success(userDto);
    }

    @PostMapping("/sendMsg")
    public Result sendMsg(@RequestBody User user, HttpSession session) {

        // 判断参数是否合法
        if (StringUtils.isAnyBlank(user.getAccount(), user.getName(), user.getPassword(), user.getEmail())
                | ValidatorUtil.isNotValidEmail(user.getEmail())) {
            throw new CustomException(ResponseCode.PARAMS_ERROR);
        }

        // 生成验证码
        Integer code = ValidateCodeUtil.generateValidateCode(6);
        log.info("验证码：{}", code);

        // 发送验证码
        emailService.sendVerificationEmail(user.getEmail(), user.getName(), code.toString(), 5);
        // 将验证码保存到session
        session.setAttribute(user.getEmail(), code);

        return Result.success();
    }

    @PostMapping("/register/{code}")
    public Result register(@RequestBody User user, @PathVariable Integer code, HttpSession session) {

        // 判断参数是否合法
        if (StringUtils.isAnyBlank(user.getAccount(), user.getName(), user.getPassword(), user.getEmail())
                || ValidatorUtil.isNotValidEmail(user.getEmail())) {
            throw new CustomException(ResponseCode.PARAMS_ERROR);
        }

        // 获取验证码
        // 需要客户端和服务端同时开启验证，否则：两次请求的session不相同无法获取codeSession
        Object codeSession = session.getAttribute(user.getEmail());


        log.info("验证码：{}", codeSession);

        // 判断验证码是否正确
        if (code == null || !code.equals(codeSession)) {
            return Result.error("验证码错误");
        }

        // 注册用户
        // 移除验证码
        session.removeAttribute(user.getEmail());

        return userService.register(user);
    }

    @PutMapping("/user")
    public Result update(@RequestBody User user) {
        // 姓名不能修改为空
        Long userId = UserContext.getUser().getId();
        if (user.getName() == null || StringUtils.isBlank(user.getName())) {
            return Result.error(ResponseCode.PARAMS_ERROR);
        }
        user.setId(userId);
        userService.updateById(user);

        return Result.success("更新成功");
    }
}
